package com.example.demo.Match;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.example.demo.Info.*;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.UUID;

@Component
public class Match {
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private Websocket_And_Room_Manage websocket_and_room_manage;
    public Queue<user_info> first_queue=new LinkedList<>();
    public Queue<user_info> next_queue=new LinkedList<>();
    public Queue<user_info> plus_queue=new LinkedList<>();
    public Queue<user_info> final_queue=new LinkedList<>();
    public Queue<user_info> max_queue=new LinkedList<>();
    public boolean matching(user_info userInfo){
        if (userInfo.getScore()<100&&userInfo.getScore()>=0){
            synchronized (first_queue) {
                if (first_queue.offer(userInfo)) {
                    first_queue.notify();
                    return true;
                } else {
                    return false;
                }
            }
        }else if (userInfo.getScore()<200&&userInfo.getScore()>=100){
            synchronized (next_queue) {
                if (next_queue.offer(userInfo)) {
                    next_queue.notify();
                    return true;
                } else {
                    return false;
                }
            }
        } else if (userInfo.getScore()<300&&userInfo.getScore()>=200) {
            synchronized (plus_queue) {
                if (plus_queue.offer(userInfo)) {
                    plus_queue.notify();
                    return true;
                } else {
                    return false;
                }
            }
        } else if(userInfo.getScore()<500&&userInfo.getScore()>=300){
            synchronized (final_queue) {
                if (final_queue.offer(userInfo)) {
                    final_queue.notify();
                    return true;
                } else {
                    return false;
                }
            }
        }else {
            synchronized (max_queue) {
                if (max_queue.offer(userInfo)) {
                    max_queue.notify();
                    return true;
                } else {
                    return false;
                }
            }
        }
    }
    public boolean unmatching(user_info userInfo){
        if (userInfo.getScore()<100&&userInfo.getScore()>=0){
            if (first_queue.remove(userInfo)){
                return true;
            }else {
                return false;
            }
        }else if (userInfo.getScore()<200&&userInfo.getScore()>=100){
            if (next_queue.remove(userInfo)){
                return true;
            }else {
                return false;
            }
        } else if (userInfo.getScore()<300&&userInfo.getScore()>=200) {
            if (plus_queue.remove(userInfo)){
                return true;
            }else {
                return false;
            }
        } else if (userInfo.getScore()<500&&userInfo.getScore()>=300){
            if (final_queue.remove(userInfo)){
                return true;
            }else {
                return false;
            }
        }else {
            if (max_queue.remove(userInfo)){
                return true;
            }else {
                return false;
            }
        }
    }
    public Match() {
        Thread first_thread=new Thread(){
            @SneakyThrows
            @Override
            public void run() {
                while (true){
                    matcher(first_queue);
                }
            }
        };
        first_thread.start();
        Thread next_thread=new Thread(){
            @SneakyThrows
            @Override
            public void run() {
                while (true){
                    matcher(next_queue);

                }
            }
        };
        next_thread.start();
        Thread plus_thread=new Thread(){
            @SneakyThrows
            @Override
            public void run() {
                while (true){
                    matcher(plus_queue);
                }
            }
        };
        plus_thread.start();
        Thread final_thread=new Thread(){
            @SneakyThrows
            @Override
            public void run() {
                while (true){
                    matcher(final_queue);
                }
            }
        };
        final_thread.start();
        Thread max_thread=new Thread(){
            @SneakyThrows
            @Override
            public void run() {
                while (true){
                    matcher(max_queue);
                }
            }
        };
        max_thread.start();
    }
    public void matcher(Queue<user_info> queue) throws InterruptedException, IOException {
        synchronized (queue){
            while (queue.size()<2){
                queue.wait();
            }
            Room room=new Room();
//            取出配对好的玩家
            user_info userInfo1=queue.poll();
            user_info userInfo2=queue.poll();
            String room_id= UUID.randomUUID().toString();
//            将房间注册到房间管理器中
            websocket_and_room_manage.room_manage.put(room_id,room);
//            将用户注册到房间-用户管理器中
            websocket_and_room_manage.room_user_manage.put(userInfo1.getUserid(),room_id);
            websocket_and_room_manage.room_user_manage.put(userInfo2.getUserid(),room_id);
//            获取两个玩家的身份标识
            WebSocketSession session1=websocket_and_room_manage.game_hall_websocket.get(userInfo1.getUserid());
            WebSocketSession session2=websocket_and_room_manage.game_hall_websocket.get(userInfo2.getUserid());
//            返回匹配成功
            Game_Hall_Websocket_Response gameHallWebsocketResponse1=new Game_Hall_Websocket_Response();
            gameHallWebsocketResponse1.setMessage("matchSuccess");
            Game_Hall_Websocket_Response gameHallWebsocketResponse2=new Game_Hall_Websocket_Response();
            gameHallWebsocketResponse2.setMessage("matchSuccess");
//            分别发送
            session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameHallWebsocketResponse1)));
            session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(gameHallWebsocketResponse2)));
        }
    }
}
